/**
 * Z-Fighting 终极修复器
 * 当其他方法都不管用时使用
 */

import * as THREE from '../../lib/three/build/three.module.js';

export class ZFightingUltimateFixer {
    /**
     * 超级强力修复 - 使用所有可能的方法
     */
    static nuclearFix(scene) {
        console.log('🚀 启动终极修复...');
        let fixedCount = 0;

        scene.traverse((obj) => {
            if (obj.isMesh && obj.material) {
                const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
                
                materials.forEach((mat, index) => {
                    // 🔧 修复：检查是否是透明材质（有alphaMap或transparent）
                    const isTransparentMaterial = mat.transparent || mat.alphaMap || mat.alphaTest > 0;
                    
                    // 方法1: 强力 polygonOffset
                    mat.polygonOffset = true;
                    mat.polygonOffsetFactor = -10 - (index * 2); // 负值向前
                    mat.polygonOffsetUnits = -10 - (index * 2);
                    
                    // 方法2: 确保深度测试开启
                    mat.depthTest = true;
                    
                    // 🔑 关键修复：透明材质不要写入深度缓冲
                    if (isTransparentMaterial) {
                        mat.depthWrite = false; // 透明材质必须禁用深度写入
                    } else {
                        mat.depthWrite = true; // 不透明材质正常写入深度
                    }
                    
                    // 方法3: 如果是透明材质，调整渲染顺序
                    if (isTransparentMaterial) {
                        obj.renderOrder = 999 + index;
                        mat.polygonOffsetFactor = 10; // 透明材质向后
                        mat.polygonOffsetUnits = 10;
                        console.log(`   🎭 透明材质检测到，已设置 depthWrite=false, renderOrder=${obj.renderOrder}`);
                    }
                    
                    // 方法4: 禁用某些可能导致问题的特性
                    mat.side = THREE.FrontSide; // 只渲染正面
                    
                    mat.needsUpdate = true;
                    fixedCount++;
                });
            }
        });

        console.log(`✅ 终极修复完成: 处理了 ${fixedCount} 个材质`);
        return fixedCount;
    }

    /**
     * 渐进式修复 - 从小到大尝试不同强度
     */
    static progressiveFix(scene) {
        console.log('🔄 启动渐进式修复...');
        
        const strategies = [
            { factor: 1, units: 1, name: '轻度' },
            { factor: 3, units: 3, name: '中度' },
            { factor: 5, units: 5, name: '强力' },
            { factor: 10, units: 10, name: '超强' },
            { factor: 20, units: 20, name: '极限' }
        ];

        console.log('请在每个级别后检查效果，如果解决了就停止。\n');

        strategies.forEach((strategy, index) => {
            console.log(`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
            console.log(`🔧 级别 ${index + 1}/5: ${strategy.name}修复`);
            console.log(`   参数: factor=${strategy.factor}, units=${strategy.units}`);
            console.log(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
            
            let count = 0;
            scene.traverse((obj) => {
                if (obj.isMesh && obj.material) {
                    const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
                    materials.forEach(mat => {
                        mat.polygonOffset = true;
                        mat.polygonOffsetFactor = -strategy.factor; // 负值
                        mat.polygonOffsetUnits = -strategy.units;
                        mat.needsUpdate = true;
                        count++;
                    });
                }
            });
            
            console.log(`✅ 已应用 ${strategy.name}修复: ${count} 个材质`);
            console.log(`💡 现在旋转场景检查效果...`);
            console.log(`   如果还有问题，5秒后会自动应用下一级别\n`);
        });

        console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
        console.log('✅ 渐进式修复完成！已应用极限级别。');
        console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
    }

    /**
     * 按材质类型分类修复
     */
    static fixByMaterialType(scene) {
        console.log('🎨 按材质类型修复...\n');
        
        const stats = {
            transparent: 0,
            opaque: 0,
            textured: 0,
            colored: 0
        };

        scene.traverse((obj) => {
            if (obj.isMesh && obj.material) {
                const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
                
                materials.forEach(mat => {
                    if (mat.transparent || mat.opacity < 1) {
                        // 透明材质：向后推
                        mat.polygonOffset = true;
                        mat.polygonOffsetFactor = 5;
                        mat.polygonOffsetUnits = 5;
                        mat.depthWrite = false; // 透明材质通常不写深度
                        stats.transparent++;
                    } else if (mat.map) {
                        // 有贴图的材质：向前拉
                        mat.polygonOffset = true;
                        mat.polygonOffsetFactor = -3;
                        mat.polygonOffsetUnits = -3;
                        stats.textured++;
                    } else if (mat.color) {
                        // 纯色材质：中等偏移
                        mat.polygonOffset = true;
                        mat.polygonOffsetFactor = -1;
                        mat.polygonOffsetUnits = -1;
                        stats.colored++;
                    } else {
                        // 其他材质：默认处理
                        mat.polygonOffset = true;
                        mat.polygonOffsetFactor = -2;
                        mat.polygonOffsetUnits = -2;
                        stats.opaque++;
                    }
                    
                    mat.depthTest = true;
                    mat.needsUpdate = true;
                });
            }
        });

        console.log('📊 修复统计:');
        console.log(`   透明材质: ${stats.transparent} 个 (向后推)`);
        console.log(`   贴图材质: ${stats.textured} 个 (向前拉)`);
        console.log(`   纯色材质: ${stats.colored} 个 (中等)`);
        console.log(`   其他材质: ${stats.opaque} 个 (默认)`);
        console.log(`   总计: ${stats.transparent + stats.textured + stats.colored + stats.opaque} 个\n`);
        console.log('✅ 按类型修复完成！');
    }

    /**
     * 物理偏移修复 - 实际移动mesh位置
     */
    static physicalOffset(scene, offset = 0.01) {
        console.log(`🔧 物理偏移修复 (偏移量: ${offset})...`);
        let count = 0;

        scene.traverse((obj) => {
            if (obj.isMesh && !obj.userData?.isGround && !obj.userData?.isHelper) {
                // 沿法线方向偏移
                if (obj.geometry && obj.geometry.attributes.normal) {
                    const positions = obj.geometry.attributes.position;
                    const normals = obj.geometry.attributes.normal;
                    
                    for (let i = 0; i < positions.count; i++) {
                        const nx = normals.getX(i);
                        const ny = normals.getY(i);
                        const nz = normals.getZ(i);
                        
                        positions.setXYZ(
                            i,
                            positions.getX(i) + nx * offset,
                            positions.getY(i) + ny * offset,
                            positions.getZ(i) + nz * offset
                        );
                    }
                    
                    positions.needsUpdate = true;
                    obj.geometry.computeBoundingBox();
                    obj.geometry.computeBoundingSphere();
                    count++;
                }
            }
        });

        console.log(`✅ 物理偏移完成: ${count} 个mesh`);
        console.log(`⚠️  警告: 这是永久性修改，如需还原请重新加载模型`);
    }

    /**
     * 禁用深度测试 (最后手段)
     */
    static disableDepthTest(scene) {
        console.log('⚠️  最后手段: 禁用深度测试...');
        let count = 0;

        scene.traverse((obj) => {
            if (obj.isMesh && obj.material) {
                const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
                materials.forEach((mat, index) => {
                    mat.depthTest = false;
                    mat.depthWrite = false;
                    obj.renderOrder = 1000 + index;
                    mat.needsUpdate = true;
                    count++;
                });
            }
        });

        console.log(`✅ 已禁用 ${count} 个材质的深度测试`);
        console.log(`⚠️  注意: 这可能导致渲染顺序混乱`);
    }

    /**
     * 完整诊断
     */
    static fullDiagnosis(scene, renderer, camera) {
        console.log('\n╔════════════════════════════════════════════════════════════╗');
        console.log('║          Z-Fighting 完整诊断报告                          ║');
        console.log('╚════════════════════════════════════════════════════════════╝\n');

        // 1. 渲染器检查
        console.log('━━━ 1. 渲染器配置 ━━━');
        console.log(`对数深度缓冲: ${renderer.capabilities.logarithmicDepthBuffer ? '✅ 已启用' : '❌ 未启用'}`);
        console.log(`抗锯齿: ${renderer.capabilities.antialias ? '✅ 已启用' : '❌ 未启用'}`);
        console.log(`像素比: ${renderer.getPixelRatio()}`);
        console.log('');

        // 2. 相机检查
        console.log('━━━ 2. 相机参数 ━━━');
        console.log(`near: ${camera.near}`);
        console.log(`far: ${camera.far}`);
        console.log(`far/near 比值: ${(camera.far / camera.near).toFixed(0)}`);
        
        if (camera.near < 0.1) {
            console.log('⚠️  警告: near 太小，建议 >= 0.1');
        }
        if (camera.far / camera.near > 100000) {
            console.log('⚠️  警告: far/near 比值太大，建议 < 10000');
        }
        console.log('');

        // 3. 场景统计
        console.log('━━━ 3. 场景统计 ━━━');
        let meshCount = 0;
        let materialCount = 0;
        let transparentCount = 0;
        let withPolygonOffset = 0;
        let withoutDepthTest = 0;

        const meshes = [];
        scene.traverse((obj) => {
            if (obj.isMesh) {
                meshCount++;
                meshes.push(obj);
                
                const materials = Array.isArray(obj.material) ? obj.material : [obj.material];
                materialCount += materials.length;
                
                materials.forEach(mat => {
                    if (mat.transparent) transparentCount++;
                    if (mat.polygonOffset) withPolygonOffset++;
                    if (!mat.depthTest) withoutDepthTest++;
                });
            }
        });

        console.log(`Mesh 总数: ${meshCount}`);
        console.log(`材质总数: ${materialCount}`);
        console.log(`透明材质: ${transparentCount}`);
        console.log(`已设置 polygonOffset: ${withPolygonOffset}`);
        console.log(`禁用深度测试: ${withoutDepthTest}`);
        console.log('');

        // 4. 重叠检测
        console.log('━━━ 4. 重叠检测 ━━━');
        const overlaps = [];
        
        for (let i = 0; i < meshes.length && i < 50; i++) {
            for (let j = i + 1; j < meshes.length && j < 50; j++) {
                const mesh1 = meshes[i];
                const mesh2 = meshes[j];
                
                if (mesh1.userData?.isGround || mesh2.userData?.isGround) continue;
                
                const pos1 = new THREE.Vector3();
                const pos2 = new THREE.Vector3();
                mesh1.getWorldPosition(pos1);
                mesh2.getWorldPosition(pos2);
                
                const distance = pos1.distanceTo(pos2);
                
                if (distance < 0.1) {
                    overlaps.push({
                        mesh1: mesh1.name || `Mesh_${i}`,
                        mesh2: mesh2.name || `Mesh_${j}`,
                        distance: distance.toFixed(6)
                    });
                }
            }
        }

        if (overlaps.length > 0) {
            console.log(`⚠️  发现 ${overlaps.length} 对可能重叠的mesh:`);
            overlaps.slice(0, 10).forEach((item, index) => {
                console.log(`   ${index + 1}. ${item.mesh1} ↔ ${item.mesh2} (距离: ${item.distance})`);
            });
        } else {
            console.log('✅ 未检测到明显重叠');
        }
        console.log('');

        // 5. 建议
        console.log('━━━ 5. 修复建议 ━━━');
        
        if (!renderer.capabilities.logarithmicDepthBuffer) {
            console.log('🔴 关键: 对数深度缓冲未启用，请检查渲染器配置');
        }
        
        if (camera.near < 0.1 || camera.far / camera.near > 100000) {
            console.log('🟡 建议: 优化相机参数 (near >= 0.1, far/near < 10000)');
        }
        
        if (withPolygonOffset === 0) {
            console.log('🟡 建议: 尚未应用 polygonOffset，运行修复命令');
        }
        
        if (overlaps.length > 10) {
            console.log('🔴 严重: 大量mesh重叠，建议使用 nuclearFix 超强修复');
        } else if (overlaps.length > 0) {
            console.log('🟡 建议: 有mesh重叠，使用 progressiveFix 渐进修复');
        }
        
        console.log('');
        console.log('╔════════════════════════════════════════════════════════════╗');
        console.log('║  推荐操作:                                                 ║');
        console.log('║  1. ultimateZFix.nuclearFix()      - 超强修复             ║');
        console.log('║  2. ultimateZFix.progressiveFix()  - 渐进修复             ║');
        console.log('║  3. ultimateZFix.fixByType()       - 按类型修复           ║');
        console.log('╚════════════════════════════════════════════════════════════╝\n');
    }
}

// 创建便捷实例
const ultimateFixer = {
    // 超强修复
    nuclearFix: () => {
        const scene = window.manager?.getCurrentScene()?.scene;
        if (!scene) {
            console.error('❌ 场景未加载');
            return;
        }
        return ZFightingUltimateFixer.nuclearFix(scene);
    },
    
    // 渐进修复
    progressiveFix: () => {
        const scene = window.manager?.getCurrentScene()?.scene;
        if (!scene) {
            console.error('❌ 场景未加载');
            return;
        }
        return ZFightingUltimateFixer.progressiveFix(scene);
    },
    
    // 按类型修复
    fixByType: () => {
        const scene = window.manager?.getCurrentScene()?.scene;
        if (!scene) {
            console.error('❌ 场景未加载');
            return;
        }
        return ZFightingUltimateFixer.fixByMaterialType(scene);
    },
    
    // 物理偏移
    physicalOffset: (offset = 0.01) => {
        const scene = window.manager?.getCurrentScene()?.scene;
        if (!scene) {
            console.error('❌ 场景未加载');
            return;
        }
        return ZFightingUltimateFixer.physicalOffset(scene, offset);
    },
    
    // 禁用深度测试 (最后手段)
    noDepth: () => {
        const scene = window.manager?.getCurrentScene()?.scene;
        if (!scene) {
            console.error('❌ 场景未加载');
            return;
        }
        return ZFightingUltimateFixer.disableDepthTest(scene);
    },
    
    // 完整诊断
    diagnose: () => {
        const currentScene = window.manager?.getCurrentScene();
        if (!currentScene) {
            console.error('❌ 场景未加载');
            return;
        }
        return ZFightingUltimateFixer.fullDiagnosis(
            currentScene.scene,
            window.manager.renderer,
            currentScene.camera
        );
    }
};

// 暴露到全局
if (typeof window !== 'undefined') {
    window.ultimateZFix = ultimateFixer;
    
    // console.log('');
    // console.log('╔════════════════════════════════════════════════════════════╗');
    // console.log('║     🚀 Z-Fighting 终极修复工具已加载！                    ║');
    // console.log('╚════════════════════════════════════════════════════════════╝');
    // console.log('');
    // console.log('📋 可用命令:');
    // console.log('');
    // console.log('  ultimateZFix.diagnose()         ← 🔍 先运行这个，完整诊断');
    // console.log('  ultimateZFix.nuclearFix()       ← 💣 超强修复 (推荐)');
    // console.log('  ultimateZFix.progressiveFix()   ← 🔄 渐进修复');
    // console.log('  ultimateZFix.fixByType()        ← 🎨 按类型修复');
    // console.log('  ultimateZFix.physicalOffset()   ← 🔧 物理偏移 (永久)');
    // console.log('  ultimateZFix.noDepth()          ← ⚠️  禁用深度 (最后手段)');
    // console.log('');
}

export default ZFightingUltimateFixer;



